package org.yeasy.cud.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ReflectUtil;

import java.util.Date;

/**
 * The type Type converter.
 * 支持的类型:
 * 1. 所有基础类型:Boolean,Byte,Short,Integer,Long,Float,Double
 * 2. String
 * 3. BigDecimal
 * 4. Date或继承类
 *
 * @author yangyishe
 * @date 2022年09月22日 14:24
 */
public class TypeConverter {
    /**
     * Calc by class object.
     *
     * @param value the value
     * @param clazz the clazz
     * @return the object
     * @author yangyishe
     * @date 2022年09月22日 14:24
     */
    public static <T> T convert(String value, Class<T> clazz) {
        if (CharSequenceUtil.isEmpty(value)) {
            return convertDefault(clazz);
        }
        if (Boolean.class == clazz) {
            return clazz.cast(Boolean.valueOf(value));
        }
        if (Number.class.isAssignableFrom(clazz) || String.class == clazz) {
            return ReflectUtil.newInstance(clazz, value);
        }
        if (Date.class.isAssignableFrom(clazz)) {
            // 支持两种格式:yyyy-MM-dd或yyyy-MM-dd hh:mm:ss
            if (DatePattern.NORM_DATE_PATTERN.length() == value.length()) {
                return clazz.cast(DateUtil.parseDate(value));
            } else {
                return clazz.cast(DateUtil.parseDateTime(value));
            }
        }
        throw new RuntimeException("not supported class:" + clazz.getName());
    }

    /**
     * Get by class t.
     *
     * @param clazz the clazz
     * @return the t
     * @author yangyishe
     * @date 2022年09月22日 10:57
     */
    public static <T> T convertDefault(Class<T> clazz) {
        if (String.class == clazz) {
            return clazz.cast("");
        }
        if (Boolean.class == clazz) {
            return clazz.cast(Boolean.FALSE);
        }
        // 此环节已经多种数字类型包括在内
        if (Number.class.isAssignableFrom(clazz)) {
            return ReflectUtil.newInstance(clazz, "0");
        }

        if (Date.class.isAssignableFrom(clazz)) {
            // 日期的默认值改为更为常见的当前值,而非1970-01-01.后者可通过设置value实现.
            return clazz.cast(new Date());
        }
        throw new RuntimeException("not supported class:" + clazz.getName());
    }
}
